/**
 * 统一认证服务
 * 提供统一的用户认证功能，支持MongoDB管理员用户和MySQL普通用户
 */

const bcrypt = require('bcrypt');
const { v4: uuidv4 } = require('uuid');
const { User } = require('../models/User');
const { generateToken, verifyToken } = require('../utils/jwt');
const { logInfo, logError, logWarning } = require('../logger');
const AdminUser = require('../admin/models/adminUser.model');

// 盐值轮数
const SALT_ROUNDS = 12;

/**
 * 统一登录服务
 * 支持普通用户（MySQL）和管理员用户（MongoDB）登录
 * @param {string} identifier - 用户标识（邮箱或用户名）
 * @param {string} password - 用户密码
 * @param {string} userType - 用户类型 ('user' | 'admin')
 * @returns {Object} 包含用户信息和访问令牌的对象
 */
async function unifiedLogin(identifier, password, userType = 'user') {
  try {
    if (userType === 'admin') {
      // 管理员用户登录（MongoDB）
      return await adminLogin(identifier, password);
    } else {
      // 普通用户登录（MySQL）
      return await userLogin(identifier, password);
    }
  } catch (error) {
    logError('统一登录失败', { error: error.message, identifier, userType });
    throw error;
  }
}

/**
 * 管理员用户登录服务
 * @param {string} username - 管理员用户名
 * @param {string} password - 管理员密码
 * @returns {Object} 包含管理员信息和访问令牌的对象
 */
async function adminLogin(username, password) {
  try {
    // 查找管理员用户
    const admin = await AdminUser.findOne({ username });

    if (!admin) {
      logWarning('管理员登录失败：用户不存在', { username });
      throw new Error('用户名或密码错误');
    }

    // 验证密码
    const isPasswordValid = await admin.validatePassword(password);

    if (!isPasswordValid) {
      logWarning('管理员登录失败：密码错误', { username });
      throw new Error('用户名或密码错误');
    }

    // 生成JWT令牌
    const token = generateToken({
      id: admin._id,
      username: admin.username,
      role: admin.role,
      isAdmin: true
    });

    // 更新管理员最后登录时间
    await admin.updateLastLogin();

    logInfo('管理员登录成功', { adminId: admin._id, username: admin.username });

    // 返回管理员信息和令牌
    return {
      user: {
        id: admin._id,
        username: admin.username,
        role: admin.role,
        lastLogin: admin.lastLogin
      },
      token
    };
  } catch (error) {
    logError('管理员登录失败', { error: error.message, username });
    throw error;
  }
}

/**
 * 普通用户登录服务
 * @param {string} email - 用户邮箱
 * @param {string} password - 用户密码
 * @returns {Object} 包含用户信息和访问令牌的对象
 */
async function userLogin(email, password) {
  try {
    // 查找用户
    const user = await User.findOne({
      where: {
        email: email
      }
    });

    if (!user) {
      logWarning('用户登录失败：用户不存在', { email });
      throw new Error('邮箱或密码错误');
    }

    // 验证密码
    const isPasswordValid = await bcrypt.compare(password, user.password_hash);

    if (!isPasswordValid) {
      logWarning('用户登录失败：密码错误', { email });
      throw new Error('邮箱或密码错误');
    }

    // 生成JWT令牌
    const token = generateToken({
      userId: user.id,
      email: user.email,
      uuid: user.uuid
    });

    logInfo('用户登录成功', { userId: user.id, email: user.email });

    // 返回用户信息和令牌
    return {
      user: {
        id: user.id,
        uuid: user.uuid,
        username: user.username,
        email: user.email,
        phone: user.phone,
        avatarUrl: user.avatarUrl,
        birthDate: user.birthDate,
        birthTime: user.birthTime,
        gender: user.gender,
        timezone: user.timezone,
        isVip: user.isVip,
        createdAt: user.createdAt
      },
      token
    };
  } catch (error) {
    logError('用户登录失败', { error: error.message, email });
    throw error;
  }
}

/**
 * 验证用户认证状态
 * @param {string} token - JWT令牌
 * @returns {Object|null} 用户信息，如果验证失败则返回null
 */
async function authenticate(token) {
  try {
    // 验证JWT令牌
    const decoded = verifyToken(token);

    if (!decoded) {
      logWarning('用户认证失败：令牌无效');
      return null;
    }

    if (decoded.isAdmin) {
      // 管理员用户认证（MongoDB）
      const admin = await AdminUser.findById(decoded.id);

      if (!admin) {
        logWarning('管理员认证失败：用户不存在', { adminId: decoded.id });
        return null;
      }

      logInfo('管理员认证成功', { adminId: admin._id, username: admin.username });
      
      // 返回管理员信息
      return {
        id: admin._id,
        username: admin.username,
        role: admin.role,
        isAdmin: true
      };
    } else {
      // 普通用户认证（MySQL）
      const user = await User.findByPk(decoded.userId);

      if (!user) {
        logWarning('用户认证失败：用户不存在', { userId: decoded.userId });
        return null;
      }

      logInfo('用户认证成功', { userId: user.id, email: user.email });
      
      // 返回用户信息
      return {
        id: user.id,
        uuid: user.uuid,
        username: user.username,
        email: user.email,
        phone: user.phone,
        avatarUrl: user.avatarUrl,
        birthDate: user.birthDate,
        birthTime: user.birthTime,
        gender: user.gender,
        timezone: user.timezone,
        isVip: user.isVip,
        createdAt: user.createdAt
      };
    }
  } catch (error) {
    logError('用户认证失败', { error: error.message });
    return null;
  }
}

module.exports = {
  unifiedLogin,
  authenticate
};